import {debounce} from '@/libs/debounce'
import {PropType} from 'vue'
import './tree.less'

interface NodeInfo {
  id: number
  name: string
  children: NodeInfo[]
}
interface CountInfo {
  id: number
  count: number
}

const TreeNode = defineComponent({
  name: 'TreeNode',
  props: {
    nodeInfo: {
      type: Object as PropType<NodeInfo>,
      required: true,
    },
    expandStatus: {
      type: Boolean,
      default: false,
    },
    direction: {
      type: String as PropType<'left' | 'right' | 'center'>,
      default: 'center',
    },
    isHaveBrother: {
      type: Boolean,
      default: false,
    },
    level: {
      type: Number,
      default: 0,
    },
  },
  emits: [
    //提交整理后的子节点数量
    'changeExpandChildCount',
  ],
  setup(props, {emit, slots}) {
    let {nodeInfo, expandStatus, direction, isHaveBrother, level} =
      toRefs(props)

    // 当前层级
    const myLevel = computed(() => {
      return level.value + 1
    })

    // 是否是根节点
    const isRoot = computed(() => {
      return myLevel.value == 1
    })

    // 当前节点宽度
    const nodeWidth = computed(() => {
      let width = '160px'
      if (isExpand.value) {
        let sumWidth = childExpandCount.value * 160
        if (sumWidth > 160) width = sumWidth + 'px'
      }
      return width
    })

    // 子节点是否展开
    const isExpand = ref(false)

    // 子节点展开的数量
    const childExpandCount = ref(0)

    // 子节点产开的信息 {id:count}
    const childCountInfo = ref<{[key: number]: number}>({})

    // 从父节点监听此节点是否打开
    watch(
      () => expandStatus.value,
      () => {
        changeExpandChildCount(childExpandCount.value)
      }
    )

    // 展开/收起子节点
    const changeExpandStatus = (nodeInfo: NodeInfo) => {
      isExpand.value = !isExpand.value
    }

    // 获取子节点的方向
    const getChildDirection = (index: number): 'left' | 'right' | 'center' => {
      let centerIndex = (nodeInfo.value.children.length - 1) / 2.0
      if (centerIndex < index) {
        return 'right'
      } else if (centerIndex > index) {
        return 'left'
      }
      return 'center'
    }

    // 处理当子节点展开之后的数据变化
    const handleChildCountChange = (countInfo: CountInfo) => {
      childCountInfo.value[countInfo.id] = countInfo.count
      childExpandCount.value = 0
      for (let key in childCountInfo.value) {
        if (childCountInfo.value[key] > 0) {
          childExpandCount.value += childCountInfo.value[key]
        }
      }
      changeExpandChildCount(childExpandCount.value)
    }

    //提交整理后的子节点数量
    const changeExpandChildCount = (count: number) => {
      let result = {id: nodeInfo.value.id, count: 0}
      if (!expandStatus.value) {
        // 当前节点为不展开状态
        result.count = 0
      } else if (isExpand.value) {
        // 子节点展开
        let children = nodeInfo.value.children
        if (children) {
          // 有子节点 则使用计算后的结果
          result.count = count
        } else {
          // 没有子节点 则为叶节点 计数1
          result.count = 1
        }
      } else {
        // 子节点不展开 也计算为叶节点 计数1
        result.count = 1
      }
      emit('changeExpandChildCount', result)
    }

    onMounted(() => {
      // 主动提交子节点状态
      changeExpandChildCount(0)
    })

    return () => {
      return (
        <div class="tree-node" style={{width: nodeWidth.value}}>
          {/* // <!-- 上方链接线  --> */}
          {isRoot.value ? (
            ''
          ) : (
            <div class="line-box">
              {isHaveBrother.value ? <div class="line-connect"></div> : ''}
              <div class={['line-to-node', direction.value]}></div>
            </div>
          )}
          {/* // <!-- 内容  --> */}
          <div
            class={[
              'content border border-default rounded',
              isRoot.value ? 'root' : '',
            ]}
          >
            {slots.content?.() || <span>{nodeInfo.value.name}</span>}
          </div>
          {/* // <!-- 下方连接线  --> */}

          {nodeInfo.value.children.length > 0 ? (
            <div class={['bottom-line-box', isExpand.value ? 'isExpand' : '']}>
              <div
                class={['control-btn', isExpand.value ? '' : 'close']}
                onClick={() => changeExpandStatus(nodeInfo.value)}
              >
                <div>{isExpand.value ? '-' : '+'}</div>
              </div>
            </div>
          ) : (
            ''
          )}
          {/* // <!-- 子节点  --> */}
          <div class={['children', isExpand.value ? '' : 'close']}>
            {nodeInfo.value.children.map((childInfo, index) => (
              <TreeNode
                nodeInfo={childInfo}
                direction={getChildDirection(index)}
                isHaveBrother={
                  nodeInfo.value.children.length > 1 &&
                  index != 0 &&
                  index != nodeInfo.value.children.length - 1
                }
                level={myLevel.value}
                expandStatus={isExpand.value}
                onChangeExpandChildCount={handleChildCountChange}
              >
                {slots}
              </TreeNode>
            ))}
          </div>
        </div>
      )
    }
  },
})

const CoustomTree = defineComponent({
  name: 'CoustomTree',
  props: {
    options: {
      type: Array as PropType<NodeInfo[]>,
      required: true,
    },
  },
  setup(props, {slots}) {
    let {options} = toRefs(props)
    onMounted(() => {})
    return () => (
      <div
        class={[
          'bg-white inline-block mx-auto rounded ',
          options.value.length > 0 ? 'p-2' : '',
        ]}
      >
        {options.value.map((nodeInfo, index) => (
          <TreeNode nodeInfo={nodeInfo}>{slots}</TreeNode>
        ))}
      </div>
    )
  },
})

export default CoustomTree
